<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<title>OpenCV: usac</title>
<link href="../../opencv.ico" rel="shortcut icon" type="image/x-icon" />
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<script type="text/javascript" src="../../tutorial-utils.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
//<![CDATA[
MathJax.Hub.Config(
{
  TeX: {
      Macros: {
          matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
          fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
          forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
          forkfour: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ #7 & \\mbox{#8}\\\\ \\end{array} \\right.", 8],
          vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
          vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9],
          cameramatrix: ["#1 = \\begin{bmatrix} f_x & 0 & c_x\\\\ 0 & f_y & c_y\\\\ 0 & 0 & 1 \\end{bmatrix}", 1],
          distcoeffs: ["(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \\tau_x, \\tau_y]]]]) \\text{ of 4, 5, 8, 12 or 14 elements}"],
          distcoeffsfisheye: ["(k_1, k_2, k_3, k_4)"],
          hdotsfor: ["\\dots", 1],
          mathbbm: ["\\mathbb{#1}", 1],
          bordermatrix: ["\\matrix{#1}", 1]
      }
  }
}
);
//]]>
</script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
<link href="../../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="../../opencv-logo-small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">OpenCV
   &#160;<span id="projectnumber">4.5.2</span>
   </div>
   <div id="projectbrief">Open Source Computer Vision</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('../../',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">usac </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><hr/>
<p> author:</p><ul>
<li>Maksym Ivashechkin bibliography: 'bibs.bib' csl: 'acm-sigchi-proceedings.csl' date: August 2020 title: 'Google Summer of Code: Improvement of Random Sample Consensus in OpenCV' ...</li>
</ul>
<h1>Contribution </h1>
<p>The integrated part to OpenCV <code>calib3d</code> module is RANSAC-based universal framework USAC (<code>namespace usac</code>) written in C++. The framework includes different state-of-the-arts methods for sampling, verification or local optimization. The main advantage of the framework is its independence to any estimation problem and modular structure. Therefore, new solvers or methods can be added/removed easily. So far it includes the following components:</p>
<ol type="1">
<li>Sampling method:<ol type="a">
<li>Uniform – standard RANSAC sampling proposed in [8] which draw minimal subset independently uniformly at random. <em>The default option in proposed framework</em>.</li>
<li>PROSAC – method [4] that assumes input data points sorted by quality so sampling can start from the most promising points. Correspondences for this method can be sorted e.g., by ratio of descriptor distances of the best to second match obtained from SIFT detector. <em>This is method is recommended to use because it can find good model and terminate much earlier</em>.</li>
<li>NAPSAC – sampling method [10] which takes initial point uniformly at random and the rest of points for minimal sample in the neighborhood of initial point. This is method can be potentially useful when models are localized. For example, for plane fitting. However, in practise struggles from degenerate issues and defining optimal neighborhood size.</li>
<li>Progressive-NAPSAC – sampler [2] which is similar to NAPSAC, although it starts from local and gradually converges to global sampling. This method can be quite useful if local models are expected but distribution of data can be arbitrary. The implemented version assumes data points to be sorted by quality as in PROSAC.</li>
</ol>
</li>
<li>Score Method. USAC as well as standard RANSAC finds model which minimizes total loss. Loss can be represented by following functions:<ol type="a">
<li>RANSAC – binary 0 / 1 loss. 1 for outlier, 0 for inlier. <em>Good option if the goal is to find as many inliers as possible.</em></li>
<li>MSAC – truncated squared error distance of point to model. <em>The default option in framework</em>. The model might not have as many inliers as using RANSAC score, however will be more accurate.</li>
<li>MAGSAC – threshold-free method [3] to compute score. Using, although, maximum sigma (standard deviation of noise) level to marginalize residual of point over sigma. Score of the point represents likelihood of point being inlier. <em>Recommended option when image noise is unknown since method does not require threshold</em>. However, it is still recommended to provide at least approximated threshold, because termination itself is based on number of points which error is less than threshold. By giving 0 threshold the method will output model after maximum number of iterations reached.</li>
<li>LMeds – the least median of squared error distances. In the framework finding median is efficiently implement with $O(n)$ complexity using quick-sort algorithm. Note, LMeds does not have to work properly when inlier ratio is less than 50%, in other cases this method is robust and does not require threshold.</li>
</ol>
</li>
<li>Error metric which describes error distance of point to estimated model.<ol type="a">
<li>Re-projection distance – used for affine, homography and projection matrices. For homography also symmetric re-projection distance can be used.</li>
<li>Sampson distance – used for Fundamental matrix.</li>
<li>Symmetric Geometric distance – used for Essential matrix.</li>
</ol>
</li>
<li>Degeneracy:<ol type="a">
<li>DEGENSAC – method [7] which for Fundamental matrix estimation efficiently verifies and recovers model which has at least 5 points in minimal sample lying on the dominant plane.</li>
<li>Collinearity test – for affine and homography matrix estimation checks if no 3 points lying on the line. For homography matrix since points are planar is applied test which checks if points in minimal sample lie on the same side w.r.t. to any line crossing any two points in sample (does not assume reflection).</li>
<li>Oriented epipolar constraint – method [6] for epipolar geometry which verifies model (fundamental and essential matrix) to have points visible in the front of the camera.</li>
</ol>
</li>
<li>SPRT verification – method [9] which verifies model by its evaluation on randomly shuffled points using statistical properties given by probability of inlier, relative time for estimation, average number of output models etc. Significantly speeding up framework, because bad model can be rejected very quickly without explicitly computing error for every point.</li>
<li>Local Optimization:<ol type="a">
<li>Locally Optimized RANSAC – method [5] that iteratively improves so-far-the-best model by non-minimal estimation. <em>The default option in framework. This procedure is the fastest and not worse than others local optimization methods.</em></li>
<li>Graph-Cut RANSAC – method [1] that refine so-far-the-best model, however, it exploits spatial coherence of the data points. <em>This procedure is quite precise however computationally slower.</em></li>
<li>Sigma Consensus – method [3] which improves model by applying non-minimal weighted estimation, where weights are computed with the same logic as in MAGSAC score. This method is better to use together with MAGSAC score.</li>
</ol>
</li>
<li>Termination:<ol type="a">
<li>Standard – standard equation for independent and uniform sampling.</li>
<li>PROSAC – termination for PROSAC.</li>
<li>SPRT – termination for SPRT.</li>
</ol>
</li>
<li>Solver. In the framework there are minimal and non-minimal solvers. In minimal solver standard methods for estimation is applied. In non-minimal solver usually the covariance matrix is built and the model is found as the eigen vector corresponding to the highest eigen value.<ol type="a">
<li>Affine2D matrix</li>
<li>Homography matrix – for minimal solver is used RHO (Gaussian elimination) algorithm from OpenCV.</li>
<li>Fundamental matrix – for 7-points algorithm two null vectors are found using Gaussian elimination (eliminating to upper triangular matrix and back-substitution) instead of SVD and then solving 3-degrees polynomial. For 8-points solver Gaussian elimination is used too.</li>
<li>Essential matrix – 4 null vectors are found using Gaussian elimination. Then the solver based on Gröbner basis described in [11] is used. Essential matrix can be computed only if <span style="font-variant:small-caps;">LAPACK</span> or <span style="font-variant:small-caps;">Eigen</span> are installed as it requires eigen decomposition with complex eigen values.</li>
<li>Perspective-n-Point – the minimal solver is classical 3 points with up to 4 solutions. For RANSAC the low number of sample size plays significant role as it requires less iterations, furthermore in average P3P solver has around 1.39 estimated models. Also, in new version of <code>solvePnPRansac(...)</code> with <code>UsacParams</code> there is an options to pass empty intrinsic matrix <code>InputOutputArray cameraMatrix</code>. If matrix is empty than using Direct Linear Transformation algorithm (PnP with 6 points) framework outputs not only rotation and translation vector but also calibration matrix.</li>
</ol>
</li>
</ol>
<p>Also, the framework can be run in parallel. The parallelization is done in the way that multiple RANSACs are created and they share two atomic variables <code>bool success</code> and <code>int num_hypothesis_tested</code> which determines when all RANSACs must terminate. If one of RANSAC terminated successfully then all other RANSAC will terminate as well. In the end the best model is synchronized from all threads. If PROSAC sampler is used then threads must share the same sampler since sampling is done sequentially. However, using default options of framework parallel RANSAC is not deterministic since it depends on how often each thread is running. The easiest way to make it deterministic is using PROSAC sampler without SPRT and Local Optimization and not for Fundamental matrix, because they internally use random generators.\ \ For NAPSAC, Progressive NAPSAC or Graph-Cut methods is required to build a neighborhood graph. In framework there are 3 options to do it:</p>
<ol type="1">
<li><code>NEIGH_FLANN_KNN</code> – estimate neighborhood graph using OpenCV FLANN K nearest-neighbors. The default value for KNN is 7. KNN method may work good for sampling but not good for GC-RANSAC.</li>
<li><code>NEIGH_FLANN_RADIUS</code> – similarly as in previous case finds neighbor points which distance is less than 20 pixels.</li>
<li><code>NEIGH_GRID</code> – for finding points’ neighborhood tiles points in cells using hash-table. The method is described in [2]. Less accurate than <code>NEIGH_FLANN_RADIUS</code>, although significantly faster.</li>
</ol>
<p>Note, <code>NEIGH_FLANN_RADIUS</code> and <code>NEIGH_FLANN_RADIUS</code> are not able to PnP solver, since there are 3D object points.\ \ New flags:</p>
<ol type="1">
<li><code>USAC_DEFAULT</code> – has standard LO-RANSAC.</li>
<li><code>USAC_PARALLEL</code> – has LO-RANSAC and RANSACs run in parallel.</li>
<li><code>USAC_ACCURATE</code> – has GC-RANSAC.</li>
<li><code>USAC_FAST</code> – has LO-RANSAC with smaller number iterations in local optimization step. Uses RANSAC score to maximize number of inliers and terminate earlier.</li>
<li><code>USAC_PROSAC</code> – has PROSAC sampling. Note, points must be sorted.</li>
<li><code>USAC_FM_8PTS</code> – has LO-RANSAC. Only valid for Fundamental matrix with 8-points solver.</li>
<li><code>USAC_MAGSAC</code> – has MAGSAC++.</li>
</ol>
<p>Every flag uses SPRT verification. And in the end the final so-far-the-best model is polished by non minimal estimation of all found inliers.\ \ A few other important parameters:</p>
<ol type="1">
<li><code>randomGeneratorState</code> – since every USAC solver is deterministic in OpenCV (i.e., for the same points and parameters returns the same result) by providing new state it will output new model.</li>
<li><code>loIterations</code> – number of iterations for Local Optimization method. <em>The default value is 10</em>. By increasing <code>loIterations</code> the output model could be more accurate, however, the computationial time may also increase.</li>
<li><code>loSampleSize</code> – maximum sample number for Local Optimization. <em>The default value is 14</em>. Note, that by increasing <code>loSampleSize</code> the accuracy of model can increase as well as the computational time. However, it is recommended to keep value less than 100, because estimation on low number of points is faster and more robust.</li>
</ol>
<p>Samples:</p>
<p>There are three new sample files in opencv/samples directory.</p>
<ol type="1">
<li><code>epipolar_lines.cpp</code> – input arguments of <code>main</code> function are two pathes to images. Then correspondences are found using SIFT detector. Fundamental matrix is found using RANSAC from tentaive correspondences and epipolar lines are plot.</li>
<li><code>essential_mat_reconstr.cpp</code> – input arguments are path to data file containing image names and single intrinsic matrix and directory where these images located. Correspondences are found using SIFT. The essential matrix is estimated using RANSAC and decomposed to rotation and translation. Then by building two relative poses with projection matrices image points are triangulated to object points. By running RANSAC with 3D plane fitting object points as well as correspondences are clustered into planes.</li>
<li><code>essential_mat_reconstr.py</code> – the same functionality as in .cpp file, however instead of clustering points to plane the 3D map of object points is plot.</li>
</ol>
<p>References:</p>
<p>1. Daniel Barath and Jiří Matas. 2018. Graph-Cut RANSAC. In <em>Proceedings of the iEEE conference on computer vision and pattern recognition</em>, 6733–6741.</p>
<p>2. Daniel Barath, Maksym Ivashechkin, and Jiri Matas. 2019. Progressive NAPSAC: Sampling from gradually growing neighborhoods. <em>arXiv preprint arXiv:1906.02295</em>.</p>
<p>3. Daniel Barath, Jana Noskova, Maksym Ivashechkin, and Jiri Matas.</p><ol type="1">
<li>MAGSAC++, a fast, reliable and accurate robust estimator. In <em>Proceedings of the iEEE/CVF conference on computer vision and pattern recognition (cVPR)</em>.</li>
</ol>
<p>4. O. Chum and J. Matas. 2005. Matching with PROSAC-progressive sample consensus. In <em>Computer vision and pattern recognition</em>.</p>
<p>5. O. Chum, J. Matas, and J. Kittler. 2003. Locally optimized RANSAC. In <em>Joint pattern recognition symposium</em>.</p>
<p>6. O. Chum, T. Werner, and J. Matas. 2004. Epipolar geometry estimation via RANSAC benefits from the oriented epipolar constraint. In <em>International conference on pattern recognition</em>.</p>
<p>7. Ondrej Chum, Tomas Werner, and Jiri Matas. 2005. Two-view geometry estimation unaffected by a dominant plane. In <em>2005 iEEE computer society conference on computer vision and pattern recognition (cVPR’05)</em>, 772–779.</p>
<p>8. M. A. Fischler and R. C. Bolles. 1981. Random sample consensus: A paradigm for model fitting with applications to image analysis and automated cartography. <em>Communications of the ACM</em>.</p>
<p>9. Jiri Matas and Ondrej Chum. 2005. Randomized RANSAC with sequential probability ratio test. In <em>Tenth iEEE international conference on computer vision (iCCV’05) volume 1</em>, 1727–1732.</p>
<p>10. D. R. Myatt, P. H. S. Torr, S. J. Nasuto, J. M. Bishop, and R. Craddock. 2002. NAPSAC: High noise, high dimensional robust estimation. In <em>In bMVC02</em>, 458–467.</p>
<p>11. Henrik Stewénius, Christopher Engels, and David Nistér. 2006. Recent developments on direct relative orientation. </p>
</div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 2 2021 11:36:34 for OpenCV by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
<script type="text/javascript">
//<![CDATA[
addTutorialsButtons();
//]]>
</script>
</body>
</html>
